package main

import (
	"bytes"
	"fmt"

	"gitee.com/dingdang4D/go-basic-exercises/routes"
	"gitee.com/dingdang4D/go-basic-exercises/services"

	"io"

	"github.com/gin-gonic/gin"
)

func main() {
	// 数据源名称 (DSN) 不包含数据库名
	dsn := "rwq:123456789@tcp(127.0.0.1:3306)/"
	// 创建数据库
	if err := services.CreateDatabase(dsn); err != nil {
		panic(err)
	}
	// 更新 DSN 以包含新创建的数据库
	dsn = "rwq:123456789@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
	// 初始化 GORM 并自动迁移
	if err := services.InitDB(dsn); err != nil {
		panic(err)
	}

	// 创建一个默认的Gin引擎
	r := gin.Default()
	// 全局注册自定义中间件
	r.Use(customMiddleware())

	// 注册用户路由组
	userRoutes := r.Group("/users")
	{
		routes.RegisterUserRoutes(userRoutes)
	}

	// 注册角色路由组
	roleRoutes := r.Group("/roles")
	{
		routes.RegisterRoleRoutes(roleRoutes)
	}

	// 启动服务器
	if err := r.Run(":8080"); err != nil {
		fmt.Println("Server start failed:", err)
	}
}

// 自定义中间件函数
func customMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 打印请求的URL
		fmt.Println()
		fmt.Println("Request Method: ", c.Request.Method)
		fmt.Println("Request URL: ", c.Request.URL.Path)

		// 读取请求体
		bodyBytes, err := io.ReadAll(c.Request.Body)
		if err != nil && err != io.EOF {
			c.JSON(500, gin.H{"error": "Failed to read request body"})
			c.Abort()
			return
		} else {
			// 打印请求体
			fmt.Println("Request Body:", string(bodyBytes))

			// 将请求体复制回io.ReadCloser，以便后续的处理器能够访问它
			c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
		}

		// 获取请求参数并打印
		queryParams := c.Request.URL.Query()
		for key, values := range queryParams {
			for _, value := range values {
				fmt.Printf("Query Param [%s]: %s\n", key, value)
			}
		}

		// 继续处理请求
		c.Next()

		// 处理请求后的逻辑（如打印状态码）
		statusCode := c.Writer.Status()
		fmt.Printf("Response Status Code: %d\n\n", statusCode)
		// 注意：这里不能直接打印响应体，因为响应可能已经开始发送给客户端了。
		//		如果你确实需要捕获和打印响应体，你可能需要深入研究Gin的响应写入机制，并编写一个自定义的ResponseWriter。
		//		但请务必小心，因为这样做可能会引入复杂性和性能问题。在大多数情况下，记录日志或使用调试工具来查看响应内容会是更好的选择。
	}

}
